import router from './router';
import { ElMessage } from 'element-plus';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import {
  getAccessToken,
  getRefreshToken,
  setAccessToken,
  setRefreshToken,
} from '@/utils/auth';
import { isHttp } from '@/utils/validate';
import { isRelogin } from '@/utils/request';
import useUserStore from '@/store/modules/user';
import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
import { refreshToken as refreshLoginToken } from '@/api/auth';
import { RESULT_CODE_SUCCESS } from '@/utils/errorCode';

NProgress.configure({ showSpinner: false });

const whiteList = ['/login', '/auth-redirect', '/bind', '/register'];

function bootstrapUserAndRoutes(to, next) {
  isRelogin.show = true;
  // 判断当前用户是否已拉取完user_info信息
  useUserStore()
    .getInfo()
    .then(() => {
      isRelogin.show = false;
      usePermissionStore()
        .generateRoutes()
        .then(accessRoutes => {
          // 根据roles权限生成可访问的路由表
          accessRoutes.forEach(route => {
            if (!isHttp(route.path)) {
              router.addRoute(route); // 动态添加可访问路由表
            }
          });
          next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
        });
    })
    .catch(err => {
      useUserStore()
        .logOut()
        .then(() => {
          ElMessage.error(err);
          next({ path: '/' });
        });
    });
}

router.beforeEach((to, from, next) => {
  NProgress.start();
  const accessToken = getAccessToken();
  if (accessToken) {
    to.meta.title && useSettingsStore().setTitle(to.meta.title);
    /* has token*/
    if (to.path === '/login') {
      next({ path: '/' });
      NProgress.done();
    } else {
      if (useUserStore().roles.length === 0) {
        bootstrapUserAndRoutes(to, next);
      } else {
        next();
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单，直接进入
      next();
    } else {
      // 没有token，尝试使用刷新令牌换取新令牌
      const refreshToken = getRefreshToken();
      if (refreshToken) {
        isRelogin.show = true;
        refreshLoginToken(refreshToken)
          .then(result => {
            if (result.code === RESULT_CODE_SUCCESS) {
              const data = result.data;
              setAccessToken(data.accessToken, data.refreshExpiresIn);
              setRefreshToken(data.refreshToken, data.refreshExpiresIn);
              // 刷新成功后，拉取用户信息并生成动态路由
              bootstrapUserAndRoutes(to, next);
            } else {
              isRelogin.show = false;
              next(`/login?redirect=${to.fullPath}`); // 刷新失败，重定向登录
              NProgress.done();
            }
          })
          .catch(() => {
            isRelogin.show = false;
            next(`/login?redirect=${to.fullPath}`);
            NProgress.done();
          });
      } else {
        next(`/login?redirect=${to.fullPath}`); // 无刷新令牌，重定向登录
        NProgress.done();
      }
    }
  }
});

router.afterEach(() => {
  NProgress.done();
});
